/*
 *    Copyright 2011 The gcal-to-refill project
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package com.googlecode.gcal2refill;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.extensions.When;
import com.itextpdf.text.BaseColor;

public class EventManager {
    private static final Logger logger = Logger.getLogger(EventManager.class
        .getName());

    public EventManager() {
        eventList = new HashMap<String, List<Event>>();
        eventDateOnlyList = new HashMap<String, List<Event>>();
        eventListHolyday = new HashMap<String, List<Event>>();
    }

    public void setCalendarEvent(List<CalendarEventEntry> eventEntry,
            BaseColor color,UserInput ui) {
        Iterator<CalendarEventEntry> iterator = eventEntry.iterator();
        while (iterator.hasNext()) {
            CalendarEventEntry entry = iterator.next();
            logger.info("entry:" + entry.getTitle().getPlainText());
            if (entry.getStatus().getValue().endsWith("canceled"))
                continue;
            for (Iterator<When> iterator1 = entry.getTimes().iterator(); iterator1
                .hasNext();) {
                When when = iterator1.next();
                logger.info("when.getStartTime:"
                    + when.getStartTime().toUiString());
                logger
                    .info("when.getEndTime:" + when.getEndTime().toUiString());
                Calendar calendarStart = Calendar.getInstance();
                calendarStart.setTime(new Date(when.getStartTime().getValue()));
                Calendar calendarEnd = Calendar.getInstance();
                calendarEnd.setTime(new Date(when.getEndTime().getValue()));
                if (!when.getStartTime().isDateOnly()) {
                    calendarStart.set(Calendar.HOUR_OF_DAY, 0);
                    calendarStart.set(Calendar.MINUTE, 0);
                    calendarStart.set(Calendar.MILLISECOND, 0);
                }
                if (!when.getEndTime().isDateOnly()) {
                    calendarEnd.set(Calendar.HOUR_OF_DAY, 0);
                    calendarEnd.set(Calendar.MINUTE, 0);
                    calendarEnd.set(Calendar.MILLISECOND, 0);
                }
                if (when.getStartTime().isDateOnly()) {
                    do {
                        String key;
                        Event mdlEvent;
                        do {
                            key =
                                (new StringBuilder(String.valueOf(String
                                    .valueOf(calendarStart.get(Calendar.YEAR)))))
                                    .append(calendarStart.get(Calendar.DAY_OF_YEAR))
                                    .toString();
                            mdlEvent =
                                new Event(
                                    color,
                                    entry.getTitle().getPlainText(),
                                    when);
                            getEventDateOnlyList(key).add(mdlEvent);
                            calendarStart.add(Calendar.DAY_OF_YEAR, 1);
                        } while (calendarStart.after(calendarEnd));
                    } while (calendarStart.before(calendarEnd));
                } else {
                    do {
                        String key;
                        Event mdlEvent;
                        key =
                            (new StringBuilder(String.valueOf(String
                                .valueOf(calendarStart.get(Calendar.YEAR)))))
                                .append(calendarStart.get(Calendar.DAY_OF_YEAR))
                                .toString();
                        mdlEvent =
                            new Event(
                                color,
                                entry.getTitle().getPlainText(),
                                when);
                        if (chkOutOfVertical(ui, when, calendarStart.getTime())){
                            getEventDateOnlyList(key).add(mdlEvent);
                        }else{
                            getEventList(key).add(mdlEvent);
                        }
                        calendarStart.add(Calendar.DAY_OF_YEAR, 1);
                    } while (!calendarStart.after(calendarEnd));
                }
            }

        }
    }

    public boolean chkOutOfVertical(UserInput userIn, When when, Date createDate) {
        Calendar calCreate = Calendar.getInstance();
        Calendar calStart = Calendar.getInstance();
        Calendar calEnd = Calendar.getInstance();
        calCreate.setTime(createDate);
        calCreate.set(Calendar.HOUR_OF_DAY, userIn.getVirticalStartTime());
        calStart.setTime(new Date(when.getStartTime().getValue()));
        calEnd.setTime(new Date(when.getEndTime().getValue()));
        if (calCreate.get(Calendar.DAY_OF_YEAR) == calEnd
            .get(Calendar.DAY_OF_YEAR) && calEnd.before(calCreate))
            return true;
        calCreate.set(Calendar.HOUR_OF_DAY, userIn.getVirticalPeriod());
        return calCreate.get(Calendar.DAY_OF_YEAR) == calEnd
            .get(Calendar.DAY_OF_YEAR) && calStart.after(calCreate);
    }

    public void setCalendarEventHoliday(List<CalendarEventEntry> eventEntry,
            BaseColor color) {
        for (Iterator<CalendarEventEntry> iterator = eventEntry.iterator(); iterator
            .hasNext();) {
            CalendarEventEntry entry = iterator.next();
            for (Iterator<When> iterator1 = entry.getTimes().iterator(); iterator1
                .hasNext();) {
                When when = iterator1.next();
                GregorianCalendar calendarStart = new GregorianCalendar();
                calendarStart.setTime(new Date(when.getStartTime().getValue()));
                GregorianCalendar calendarEnd = new GregorianCalendar();
                calendarEnd.setTime(new Date(when.getEndTime().getValue()));
                if (!when.getStartTime().isDateOnly()) {
                    calendarStart.set(Calendar.HOUR_OF_DAY, 0);
                    calendarStart.set(Calendar.MINUTE, 0);
                    calendarStart.set(Calendar.MILLISECOND, 0);
                }
                if (!when.getEndTime().isDateOnly()) {
                    calendarStart.set(Calendar.HOUR_OF_DAY, 0);
                    calendarStart.set(Calendar.MINUTE, 0);
                    calendarStart.set(Calendar.MILLISECOND, 0);
                }
                do {
                    String key =
                        (new StringBuilder(String.valueOf(String
                            .valueOf(calendarStart.get(Calendar.YEAR)))))
                            .append(calendarStart.get(Calendar.DAY_OF_YEAR))
                            .toString();
                    Event mdlEvent =
                        new Event(color, entry.getTitle().getPlainText(), when);
                    List<Event> eventList = getEventHolidayList(key);
                    eventList.add(mdlEvent);
                    calendarStart.add(Calendar.DAY_OF_YEAR, 1);
                } while (!calendarStart.equals(calendarEnd));
            }

        }

    }

    private List<Event> getEventHolidayList(String strStartKey) {
        List<Event> eventList = eventListHolyday.get(strStartKey);
        if (eventList == null) {
            eventList = new ArrayList<Event>();
            eventListHolyday.put(strStartKey, eventList);
        }
        return eventList;
    }

    private List<Event> getEventDateOnlyList(String strStartKey) {
        List<Event> eventList = eventDateOnlyList.get(strStartKey);
        if (eventList == null) {
            eventList = new ArrayList<Event>();
            eventDateOnlyList.put(strStartKey, eventList);
        }
        return eventList;
    }

    private List<Event> getEventList(String strStartKey) {
        List<Event> eventList = this.eventList.get(strStartKey);
        if (eventList == null) {
            eventList = new ArrayList<Event>();
            this.eventList.put(strStartKey, eventList);
        }
        return eventList;
    }

    public HashMap<String, List<Event>> getEventList() {
        return eventList;
    }

    public HashMap<String, List<Event>> getEventDateOnlyList() {
        return eventDateOnlyList;
    }

    public HashMap<String, List<Event>> getEventListHolyday() {
        return eventListHolyday;
    }

    private HashMap<String, List<Event>> eventList;
    private HashMap<String, List<Event>> eventDateOnlyList;
    private HashMap<String, List<Event>> eventListHolyday;
}
